package com.heyige.facade;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.heyige.dto.ChatDto;
import com.heyige.entity.AiMessage;
import com.heyige.entity.AiSession;
import com.heyige.entity.User;
import com.heyige.exception.BusinessException;
import com.heyige.exception.ErrorCode;
import com.heyige.service.AiMessageService;
import com.heyige.service.AiSessionService;
import com.heyige.service.UserService;
import com.heyige.service.ai.AiModelManager;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
public class ChatSessionFacade {

    private final AiSessionService aiSessionService;
    private final AiMessageService aiMessageService;
    private final UserService userService;
    private final AiModelManager aiModelManager;

    /**
     * 创建聊天会话
     *
     * @param userId  用户ID
     * @param request 创建会话请求
     * @return 会话响应
     */
    @Transactional
    public ChatDto.SessionResponse createSession(Long userId, ChatDto.CreateSessionRequest request) {
        // 检查用户是否存在
        User user = userService.getById(userId);
        if (null == user) {
            throw new BusinessException(ErrorCode.USER_NOT_FOUND);
        }
        // 创建会话
        AiSession session = new AiSession();
        session.setUserId(userId);
        session.setTitle(request.getTitle());
        session.setLastMessageTime(LocalDateTime.now());

        // 设置模型类型
        if (request.getModel() != null && !request.getModel().isEmpty()) {
            try {
                session.setModelType(AiSession.ModelType.valueOf(request.getModel().toUpperCase()).name());
            } catch (IllegalArgumentException e) {
                session.setModelType(AiSession.ModelType.CHATGPT.name());
            }
        } else {
            session.setModelType(AiSession.ModelType.CHATGPT.name());
        }
        aiSessionService.save(session);
        // 构建响应
        return buildSessionResponse(session);
    }

    /**
     * 获取用户的会话列表
     *
     * @param userId 用户ID
     * @param active 是否只获取活跃会话
     * @param page   分页参数
     * @param size   分页参数
     * @return 会话列表
     */
    public IPage<ChatDto.SessionResponse> getUserSessions(Long userId, Boolean active, Integer page, Integer size) {
        // 检查用户是否存在
        User user = userService.getById(userId);
        if (null == user) {
            throw new BusinessException(ErrorCode.USER_NOT_FOUND);
        }
        Page<AiSession> sessionPage = aiSessionService.page(new Page<>(page, size),
                new LambdaQueryWrapper<AiSession>().eq(AiSession::getUserId, userId)
                        .eq(AiSession::getIsActive, active)
                        .orderByDesc(AiSession::getLastMessageTime)
        );
        return sessionPage.convert(this::buildSessionResponse);
    }

    /**
     * 获取会话详情
     *
     * @param sessionId 会话ID
     * @param userId    用户ID
     * @return 会话响应
     */
    public ChatDto.SessionResponse getSession(Long sessionId, Long userId) {
        AiSession session = aiSessionService.getOne(new LambdaQueryWrapper<AiSession>().eq(AiSession::getUserId, userId).eq(AiSession::getId, sessionId));
        if (null == session) {
            throw new BusinessException(ErrorCode.CHAT_SESSION_NOT_FOUND);
        }
        return buildSessionResponse(session);
    }

    /**
     * 删除会话
     *
     * @param sessionId 会话ID
     * @param userId    用户ID
     */
    @Transactional
    public void deleteSession(Long sessionId, Long userId) {
        AiSession session = aiSessionService.getOne(new LambdaQueryWrapper<AiSession>().eq(AiSession::getUserId, userId).eq(AiSession::getId, sessionId));
        if (null == session) {
            throw new BusinessException(ErrorCode.CHAT_SESSION_NOT_FOUND);
        }
        // 软删除会话
        session.setIsActive(false);
        aiSessionService.save(session);
        log.info("用户 {} 删除会话 {}", userId, sessionId);
    }

    /**
     * 发送聊天消息
     *
     * @param userId  用户ID
     * @param request 聊天请求
     * @return 聊天响应
     */
    @Transactional
    public ChatDto.ChatResponse sendMessage(Long userId, ChatDto.ChatRequest request) {
        // 检查会话是否存在且属于该用户
        Long sessionId = request.getSessionId();
        AiSession session = getSessionByIdAndUserId(sessionId, userId);
        // 检查会话是否活跃
        if (!session.getIsActive()) {
            throw new BusinessException(ErrorCode.CHAT_SESSION_CLOSED);
        }

        // 保存用户消息
        AiMessage userMessage = new AiMessage();
        userMessage.setSessionId(sessionId);
        userMessage.setRole(AiMessage.MessageRole.USER.name());
        userMessage.setContent(request.getContent());
        aiMessageService.save(userMessage);

        try {
            // 调用AI模型
            ChatDto.ChatResponse aiResponse = aiModelManager.chatWithFallback(request);

            // 保存AI回复消息
            AiMessage aiMessage = new AiMessage();
            aiMessage.setSessionId(sessionId);
            aiMessage.setRole(AiMessage.MessageRole.ASSISTANT.name());
            aiMessage.setContent(aiResponse.getContent());
            aiMessage.setTokens(aiResponse.getTokens());
            aiMessageService.save(aiMessage);

            // 更新会话信息
            session.incrementMessageCount();
            session.addTokens(aiResponse.getTokens());
            session.setLastMessageTime(LocalDateTime.now());
            aiSessionService.save(session);

            // 更新响应中的模型信息
            aiResponse.setModel(aiResponse.getModel());

            return aiResponse;

        } catch (Exception e) {
            log.error("AI模型调用失败", e);

            // 保存错误消息
            AiMessage errorMessage = new AiMessage();
            errorMessage.setSessionId(sessionId);
            errorMessage.setRole(AiMessage.MessageRole.ASSISTANT.name());
            errorMessage.setContent("抱歉，AI服务暂时不可用，请稍后再试。");
            aiMessageService.save(errorMessage);

            throw new BusinessException(ErrorCode.AI_MODEL_SERVICE_UNAVAILABLE);
        }
    }

    /**
     * 获取会话的聊天历史
     *
     * @param sessionId 会话ID
     * @param userId    用户ID
     * @return 聊天历史列表
     */
    public List<AiMessage> getChatHistory(Long sessionId, Long userId) {
        // 检查会话是否存在且属于该用户
        AiSession session = aiSessionService.getOne(new LambdaQueryWrapper<AiSession>().eq(AiSession::getUserId, userId).eq(AiSession::getId, sessionId));
        if (null == session) {
            throw new BusinessException(ErrorCode.CHAT_SESSION_NOT_FOUND);
        }

        return aiMessageService.list(new LambdaQueryWrapper<AiMessage>()
                .eq(AiMessage::getSessionId, sessionId)
                .orderByAsc(AiMessage::getCreatedAt));
    }

    /**
     * 清除会话的聊天历史
     *
     * @param sessionId 会话ID
     * @param userId    用户ID
     */
    @Transactional
    public void clearChatHistory(Long sessionId, Long userId) {
        // 检查会话是否存在且属于该用户
        AiSession session = getSessionByIdAndUserId(sessionId, userId);
        // 软删除所有消息
        List<AiMessage> messages = getMessagesBySessionId(sessionId);
        for (AiMessage message : messages) {
            message.setIsDeleted(true);
            aiMessageService.save(message);
        }

        // 重置会话统计信息
        session.setMessageCount(0);
        session.setTotalTokens(0);
        aiSessionService.save(session);
        log.info("用户 {} 清除会话 {} 的聊天历史", userId, sessionId);
    }

    /**
     * 更新会话标题
     *
     * @param sessionId 会话ID
     * @param userId    用户ID
     * @param title     新标题
     * @return 更新后的会话响应
     */
    @Transactional
    public ChatDto.SessionResponse updateSessionTitle(Long sessionId, Long userId, String title) {
        AiSession session = getSessionByIdAndUserId(sessionId, userId);
        session.setTitle(title);
        aiSessionService.save(session);
        return buildSessionResponse(session);
    }

    /**
     * 构建会话响应
     *
     * @param session 会话实体
     * @return 会话响应
     */
    private ChatDto.SessionResponse buildSessionResponse(AiSession session) {
        ChatDto.SessionResponse response = new ChatDto.SessionResponse();
        response.setId(session.getId());
        response.setUserId(session.getUserId());
        response.setTitle(session.getTitle());
        response.setModelType(session.getModelType());
        response.setMessageCount(session.getMessageCount());
        response.setTotalTokens(session.getTotalTokens());
        response.setIsActive(session.getIsActive());

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        response.setLastMessageTime(session.getLastMessageTime().format(formatter));
        response.setCreatedAt(session.getCreatedAt().format(formatter));

        return response;
    }

    private AiSession getSessionByIdAndUserId(Long sessionId, Long userId) {
        AiSession session = aiSessionService.getOne(new LambdaQueryWrapper<AiSession>().eq(AiSession::getUserId, userId).eq(AiSession::getId, sessionId));
        if (null == session) {
            throw new BusinessException(ErrorCode.CHAT_SESSION_NOT_FOUND);
        }
        return session;
    }

    private List<AiMessage> getMessagesBySessionId(Long sessionId) {
        return aiMessageService.list(new LambdaQueryWrapper<AiMessage>().eq(AiMessage::getSessionId, sessionId).orderByAsc(AiMessage::getCreatedAt));
    }
}